#include "FI_OMOData.h"
#include <bondlib/BondCalendar.h>
#include <core/time/time.h>
#include <msgcenter/FIMsgProcess.h>
#include <qbkernel/include/qb_base.h>
#include <qbprotocol/include/rdProto.h>
#include <qbprotocol/include/SSFIModel.h>
#include <qbtools/message/MessagePoster.h>
#include <uam/ServerTimeMgr.h>
#include <uam/UserAccountManager.h>
#include <qbprotocol/include/SSQBAModel.h>

////净投放
CashDelivery::CashDelivery(){
	for (int i = 0; i < 3; i++)
	{
		data_.push_back(0.0);
	}
}
CashDelivery::~CashDelivery() {
}

void CashDelivery::setTodayData(double val) {
	data_[TODAY] = val;
}

void CashDelivery::setWeekData(double val) {
	data_[WEEK] = val;
}

void CashDelivery::setMonthData(double val) {
	data_[MONTH] = val;
}

double CashDelivery::getData(int emdate) {
	return data_[emdate];
}

void FIOMOData::reqData(MessageReceiver* msgRecv)
{
	static bool reqOnce = false;
	if (reqOnce)return;
	reqOnce = true;

	QBAPublicOptionReq req;

	time_t tToday = ServerTimeMgr::instance().serverTime();
	if (tToday == 0)tToday = time(0);

	tm tmBegin = qb::base::time2tm(tToday);
	//今天前一年
	req.m_beginDate = (tmBegin.tm_year + 1900 - 1) * 10000 + (tmBegin.tm_mon + 1) * 100 + tmBegin.tm_mday;
	//今天后5
	int days = 0;
	while (days < 5) {//银行间日历取当日后5个工作日
		CBondCalendar::GetNextTradingDay(tToday, true);
		days++;
	}

	tm tmEnd = qb::base::time2tm(tToday);
	req.m_endDate = (tmEnd.tm_year + 1900) * 10000 + (tmEnd.tm_mon + 1) * 100 + tmEnd.tm_mday;

	if (req.m_beginDate == m_req.m_beginDate && req.m_endDate == m_req.m_endDate)
		return;

	m_req = req;
	qb::SSRequestMsg msg;
	msg.m_pRequest = &m_req;
	msg.m_FuncID = E_FID_QBA_PUBLIC_OPTION_V2_REQ;
	MessagePoster poster(&msg, qbmsg::fixedincome::EncodeFunc);
	poster.send(msgRecv);
}

bool FIOMOData::onReceive(int32_t funcId, const qb::SSAckMsg& msg)
{
	if (funcId == E_FID_QBA_PUBLIC_OPTION_V2_REQ || funcId == E_FID_QBA_PUBLIC_OPTION_V2_PUSH)
	{
		xQBAPublicOptionListV2_c* pdata = (xQBAPublicOptionListV2_c*)msg.m_pRet;
		if (!pdata)return false;
		SCOPED_MUTEX(m_lock);
		m_lstFlash.clear();
		for (auto itr = pdata->m_List.begin(); itr != pdata->m_List.end(); ++itr)
		{
			const xQBAPublicOptionUnit_c& pUnit = *itr;

			if (pUnit.m_Date<m_req.m_beginDate || pUnit.m_Date>m_req.m_endDate)continue;

			bool bExist = false;
			for (auto it = m_lstPubOpr.begin(); it != m_lstPubOpr.end(); it++)
			{
				if (it->m_Date == pUnit.m_Date && strcmp(it->m_Type, pUnit.m_Type) == 0 && strcmp(it->m_TermType, pUnit.m_TermType) == 0)
				{
					*it = pUnit;
					bExist = true;
					break;
				}
			}

			if (funcId == E_FID_QBA_PUBLIC_OPTION_V2_PUSH)
			{
				QString strID = QString("%1.%2")
					.arg(pUnit.m_Date)
					.arg(QString::fromLocal8Bit(pUnit.m_Type));
				m_lstFlash.push_back(strID);
			}
			if (bExist)continue;
			m_lstPubOpr.push_back(pUnit);
		}

		for (auto itr = pdata->m_DelList.begin(); itr != pdata->m_DelList.end(); ++itr)
		{
			const xQBAPublicOptionUnit_c& pUnit = *itr;

			if (pUnit.m_Date<m_req.m_beginDate || pUnit.m_Date>m_req.m_endDate)continue;

			for (auto it = m_lstPubOpr.begin(); it != m_lstPubOpr.end(); )
			{
				if (it->m_Date == pUnit.m_Date && strcmp(it->m_Type, pUnit.m_Type) == 0 && strcmp(it->m_TermType, pUnit.m_TermType) == 0)
				{
					it = m_lstPubOpr.erase(it);
					break;
				}
				it++;
			}
		}

		if (!pdata->m_NetInvList.empty())
		{
			m_lstInv.clear();
			for (auto it = pdata->m_NetInvList.begin(); it != pdata->m_NetInvList.end(); it++)
			{
				const QBAPubOptNetInvFactor& inv = *it;
				m_lstInv.push_back(inv);
				auto itLast = m_lstInv.rbegin();
				if (itLast != m_lstInv.rend())
				{
					QString strName = QString::fromLocal8Bit(itLast->name.c_str());
					strName.replace("\\r\\n", "\r\n");
					itLast->name = strName.toStdString();
					strName = QString::fromLocal8Bit(itLast->name_en.c_str());
					strName.replace("\\r\\n", "\r\n");
					itLast->name_en = strName.toStdString();
				}
			}
		}

		////将日期默认展示顺序调整为，今日 -> 未来 ( 升序 )-> 过去 ( 降序 ) ，即：T, T+1, T+2 ... T+7, T-1, T-2, T-3...
		UINT nToday = ServerTimeMgr::instance().today();

		std::list<xQBAPublicOptionUnit_c> lstFuture;
		std::list<xQBAPublicOptionUnit_c> lstLast;
		for (auto itr = m_lstPubOpr.begin(); itr != m_lstPubOpr.end(); ++itr) {
			const xQBAPublicOptionUnit_c& unit = *itr;
			if (unit.m_Date >= nToday) {
				lstFuture.push_back(unit);
			}
			else {
				lstLast.push_back(unit);
			}
		}
		lstFuture.sort();
		lstLast.sort();
		m_lstPubOpr.clear();
		m_lstPubOpr.insert(m_lstPubOpr.end(), lstLast.begin(), lstLast.end());
		m_lstPubOpr.insert(m_lstPubOpr.end(), lstFuture.rbegin(), lstFuture.rend());

		calcNetRelease();
		
		return true;
	}
	else if (funcId == E_FID_QBA_PUBLIC_OPTION_SETTING_QRY_V2)
	{
		xQBAPubOptSettingV2Ack* pdata = (xQBAPubOptSettingV2Ack*)msg.m_pRet;
		if (!pdata) return false;

		bool InvDefault = (pdata->m_nInitFlag == 0);
		m_setInvSetting.clear();
		QStringList arrSelect;
		QString szSelect = QString(pdata->m_Select);
		arrSelect = szSelect.split((","));

		for (int i = 0; i < arrSelect.size(); i++)
		{
			const QString& sID = arrSelect[i];
			if (!sID.isEmpty())
			{
				m_setInvSetting.insert(sID.toInt());
			}
		}
		if (msg.m_IsReceving == 0)
		{
			if (InvDefault && m_setInvSetting.size() <= 0)
			{
				for (auto it = m_lstInv.begin(); it != m_lstInv.end(); it++)
				{
					if (it->dft == 1)
						m_setInvSetting.insert(it->id);
				}
			}
			calcNetRelease();
		}
		return true;
	}

	return false;
}

void FIOMOData::calcNetRelease()
{
	double dToday = 0.0f;
	double dWeek = 0.0f;
	double dMonth = 0.0f;
	for (auto id : m_setInvSetting)
	{
		for (auto it1 = m_lstInv.begin(); it1 != m_lstInv.end(); it1++)
		{
			if (id == it1->id)
			{
				dToday += it1->value;
				dWeek += it1->weekValue;
				dMonth += it1->monthValue;
				break;
			}
		}
	}
	m_cashDelivery.setTodayData(dToday);
	m_cashDelivery.setWeekData(dWeek);
	m_cashDelivery.setMonthData(dMonth);
}

double FIOMOData::netRelease(CashDeliveryType eType)
{
	return m_cashDelivery.getData(eType);
}

void FIOMOData::reqSetting(MessageReceiver* msgRecv)
{
	xQBAPubOptSettingV2Req req;
	FIELDCOPY(req.m_UserId, SSUserAccountManager::instance().GetUserInfo().m_UserId);

	qb::SSRequestMsg msg;
	msg.m_pRequest = &req;
	msg.m_FuncID = E_FID_QBA_PUBLIC_OPTION_SETTING_QRY_V2;
	MessagePoster poster(&msg, qbmsg::fixedincome::EncodeFunc);
	poster.send(msgRecv);
}

void FIOMOData::saveSetting(MessageReceiver* msgRecv)
{
	QString szSetting, szTemp;
	int i = 0;
	for (auto it = m_setInvSetting.begin(); it != m_setInvSetting.end(); it++, i++)
	{
		if (i > 0)szSetting += QString(",");
		szTemp = (QString("%1").arg(*it));
		szSetting += szTemp;
	}

	xQBAPubOperSettingAddV2Req req;
	FIELDCOPY(req.m_UserId, SSUserAccountManager::instance().GetUserInfo().m_UserId);
	FIELDCOPY(req.m_Select, szSetting.toLocal8Bit().data());
	req.m_nInitFlag = 1;

	qb::SSRequestMsg msg;
	msg.m_pRequest = &req;
	msg.m_FuncID = E_FID_QBA_PUBLIC_OPTION_SETTING_ADD_V2;
	MessagePoster poster(&msg, qbmsg::fixedincome::EncodeFunc);
	poster.send(msgRecv);
}